package com.young.dubbo.protocol.dubbo;

import com.young.dubbo.framework.URL;
import com.young.dubbo.register.ZookeeperRegister;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.serialization.ClassResolvers;
import io.netty.handler.codec.serialization.ObjectDecoder;
import io.netty.handler.codec.serialization.ObjectEncoder;

/**
 * 模拟远程服务器
 */
public class NettyServer {
    /**
     * 启动服务器
     * @param hostName
     * @param port
     */
    public void start(String  hostName,int port,String interfaceName){
        // 先进行注册中心的注册
        // 已zookeeper 作为注册中心
        ZookeeperRegister.register(interfaceName,new URL(hostName,port));

        // 创建server 端的引导服务类，负责初始化netty服务器
        ServerBootstrap serverBootstrap = new ServerBootstrap();
        // 本质是一个线程池，用于处理
        NioEventLoopGroup eventLoopGroup = new NioEventLoopGroup();
        // 绑定线程组，设置react模式的主线程池 以及 IO 操作线程池,实质调用的是group(bossGroup, workerGroup)
        serverBootstrap.group(eventLoopGroup)
                .channel(NioServerSocketChannel.class)//设置通讯模式，调用的是实现io.netty.channel.Channel接口的类。如：NioSocketChannel、NioServerSocketChannel
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    /*  childHandler / childOption / childAttr 方法（只有服务端ServerBootstrap才有child类型的方法）
                    对于服务端而言，有两种通道需要处理， 一种是ServerSocketChannel：用于处理用户连接的accept操作， 另一种是SocketChannel，表示对应客户端连接。而对于客户端，一般都只有一种channel，也就是SocketChannel。*/
                    @Override
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        ChannelPipeline pipeline = socketChannel.pipeline();
                        // 每个channel 中都维护了一个 channelPipline,ChannelPipeline内部包含了N个handler，每一个handler都是由一个线程去执行；
                        pipeline.addLast("decoder",new ObjectDecoder(
                                ClassResolvers.weakCachingConcurrentResolver(this.getClass().getClassLoader())));
                        pipeline.addLast("encoder",new ObjectEncoder());
                        pipeline.addLast("handler",new NettyServerHandler());
                    }
                });
        try {
            // 绑定端口以及地址，开始接收进来的连接
            // sync 阻塞 线程 阻止程序结束
            System.out.println("netty 服务启动........");
            serverBootstrap.bind(hostName, port).sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void close(){

    }
}
